package com.project2.aspect;


import com.project2.anno.SaveLog;
import com.project2.bean.ResultVo;
import com.project2.bean.bo.CartAddBo;
import com.project2.bean.bo.OrderDBO;
import com.project2.bean.bo.OrderShipBO;
import com.project2.bean.bo.WxOrderMBO;
import com.project2.bean.po.MarketAdmin;
import com.project2.bean.po.MarketLog;
import com.project2.bean.po.MarketUser;
import com.project2.mapper.MarketLogMapper;
import com.project2.service.MarketLogService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * @author : bunnyupup
 * @description :
 * @date : Created in 2022/8/14 13:25
 */
@Aspect
@Component
public class LogAspect {
    @Autowired
    MarketLogService marketLogService;

    @Autowired
    MarketLogMapper marketLogMapper;

    @Autowired
    HttpServletRequest httpServletRequest;

    // 切点
    @Pointcut("execution(* com..controller..*(..))")
    public void logPointcut() {

    }

    @Around("logPointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        MarketLog marketLog = new MarketLog();
        if (httpServletRequest.getRequestURI().contains("/admin/")) {
            String name;
            name = (String) httpServletRequest.getSession().getAttribute("username");

            if (name == null) {
                name = "匿名用户";
            }
            // 执行委托方法
//        Object proceed = joinPoint.proceed();
//        ResultVo resultVo = (ResultVo)joinPoint.proceed();

            // 获取织入点方法
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            // 获取操作——方法上的saveLog的值
            // 判断方法上是否有该注解
            if (method.isAnnotationPresent(SaveLog.class)) {
                // 获取注解值
                SaveLog saveLog = method.getAnnotation(SaveLog.class);
                ResultVo resultVo = (ResultVo) joinPoint.proceed();
                // 用户名 admin

                Subject subject = SecurityUtils.getSubject();
                PrincipalCollection principals = subject.getPrincipals();

//        if (principals == null) {
//            marketLog.setAdmin("匿名用户");
//        }
                if (subject.isAuthenticated()) {
                    name = ((MarketAdmin) principals.getPrimaryPrincipal()).getUsername();
                }
                // ip
                String ip = httpServletRequest.getRemoteHost();
                marketLog.setIp(ip);
                // 操作时间
                Date date = new Date();
                marketLog.setAddTime(date);
                marketLog.setUpdateTime(date);
                // 保存type
                int type = saveLog.type();

                // 操作动作 action
                String value = saveLog.value();
                System.out.println(value);
                marketLog.setAction(value);

                //状态
                boolean status = false;
                if (resultVo.getErrno() == 0) {
                    status = true;
                }
                // 操作状态 result 要分具体业务
                // 登录业务
                if (value.equals("登录") || value.equals("退出")) {
                    if (resultVo.getErrno() == 0) {
                        marketLog.setResult("成功");
                        marketLog.setComment(saveLog.comment());
                    } else {
                        marketLog.setResult("失败");
                        marketLog.setComment("用户帐号或密码不正确");
                    }
                }
                // 管理员相关：添加、编辑、删除
                if (value.equals("添加管理员") || value.equals("编辑管理员")) {
//                Object data = resultVo.getData();
//                String result = ((MarketAdmin) data).getUsername(); // 参数校验会报错
                    // 获得参数
                    Object[] args = joinPoint.getArgs();
                    String result = ((MarketAdmin) args[0]).getUsername();
                    marketLog.setResult(result);
                } else if (value.equals("删除管理员")) {
                    // 获得参数
                    Object[] args = joinPoint.getArgs();
                    String result = ((MarketAdmin) args[0]).getUsername();
                    marketLog.setResult(result);
                }
                // 订单相关：发货，退款、删除订单
                if (value.equals("发货")) {
                    type = 2;
                    // 获得参数
                    Object[] args = joinPoint.getArgs();
                    Integer orderId = ((OrderShipBO) args[0]).getOrderId();
                    // 通过参数的orderId获得订单编号
                    String orderSn = marketLogMapper.queryOrderSnById(orderId);
                    marketLog.setResult("订单编号 " + orderSn);
                } else if (value.equals("退款") || value.equals("删除订单")) {
                    type = 2;
                    Object[] args = joinPoint.getArgs();
                    Integer orderId = ((OrderDBO) args[0]).getOrderId();
                    String orderSn = marketLogMapper.queryOrderSnById(orderId);
                    marketLog.setResult("订单编号 " + orderSn);
                }
                marketLog.setAdmin(name);
                marketLog.setType(type);
                marketLog.setStatus(status);
                marketLog.setDeleted(false);
                // 保存到日志
                marketLogService.saveLog(marketLog);
                return resultVo;
            }
        } else if (httpServletRequest.getRequestURI().contains("/wx/")) {
            // 获取织入点方法
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            // 获取操作——方法上的saveLog的值
            // 判断方法上是否有该注解
            if (method.isAnnotationPresent(SaveLog.class)) {
                // 获取注解值
                SaveLog saveLog = method.getAnnotation(SaveLog.class);
                ResultVo resultVo = (ResultVo) joinPoint.proceed();
                // 用户名 admin

                Subject subject = SecurityUtils.getSubject();
                PrincipalCollection principals = subject.getPrincipals();

//        if (principals == null) {
//            marketLog.setAdmin("匿名用户");
//        }
                if (subject.isAuthenticated()) {
                    String username = ((MarketUser) principals.getPrimaryPrincipal()).getUsername();
                    marketLog.setAdmin(username);
                }
                // ip
                String ip = httpServletRequest.getRemoteHost();
                marketLog.setIp(ip);
                // 操作时间
                Date date = new Date();
                marketLog.setAddTime(date);
                marketLog.setUpdateTime(date);
                // 保存type
                int type = saveLog.type();

                // 操作动作 action
                String value = saveLog.value();
                System.out.println(value);
                marketLog.setAction(value);

                //状态
                boolean status = false;
                if (resultVo.getErrno() == 0) {
                    status = true;
                }
                // 操作状态 result 要分具体业务
                // 登录业务
                if (value.equals("小程序用户登录") || value.equals("小程序用户退出")) {
                    if (resultVo.getErrno() == 0) {
                        marketLog.setResult("成功");
                        marketLog.setComment(saveLog.comment());
                    } else {
                        marketLog.setResult("失败");
                        marketLog.setComment("用户帐号或密码不正确");
                    }
                }
                //
                if (value.equals("小程序用户申请退款")) {
                    type = 2;
                    // 获得参数
                    Object[] args = joinPoint.getArgs();
                    Integer orderId = ((WxOrderMBO) args[0]).getOrderId();
                    // 通过参数的orderId获得订单编号
                    String orderSn = marketLogMapper.queryOrderSnById(orderId);
                    marketLog.setResult("订单编号 " + orderSn);
                } else if (value.equals("小程序用户加购商品")) {
                    Object[] args = joinPoint.getArgs();
                    Integer goodsId = ((CartAddBo) args[0]).getGoodsId();
                    marketLog.setResult("商品编号 " + goodsId);
                } else if (value.equals("用户已付款")) {
                    if (resultVo.getErrno() == 0) {
                        marketLog.setResult("成功");
                    }
                }

                marketLog.setType(type);
                marketLog.setStatus(status);
                marketLog.setDeleted(false);
                // 保存到日志
                marketLogService.saveLog(marketLog);
                return resultVo;
            }
        }

        // 执行委托方法
        Object proceed = joinPoint.proceed();
        return proceed;
    }
}
